﻿#pragma once
#include <memory>
#include <vector>

class CommandLine;
class Parser;
class System;
class Mesh;
class Executioner;
class Action;
class Output;
class UserObject;

class Application
{
public:
  Application(int argc, char** argv);
  virtual ~Application();

  virtual void PrintLogo();

  // 解析命令行
  virtual void ParseCLI();

  // 解析配置文件
  virtual void ParseInputFile();

  virtual void Run();

  void AddOutput(std::shared_ptr<Output> output);
  void AddUserObject(std::shared_ptr<UserObject> output);

  std::shared_ptr<Parser>& GetParser() { return this->_parser; }
  std::shared_ptr<Mesh>& GetMesh() { return this->_mesh; }
  std::shared_ptr<System>& GetSystem() { return this->_system; }

  template<typename T>
  T& GetSystem()
  {
    static_assert(std::is_base_of<System, T>::value, "convert error");
    return static_cast<T&>(*_system);
  }
  std::shared_ptr<Executioner>& GetExecutioner() { return this->_executioner; }

  std::vector<std::shared_ptr<Output>>& GetOutputWarehouse() { return this->_owh; }
  std::vector<std::shared_ptr<UserObject>>& GetUserObjectWarehouse() { return this->_uos; }

protected:
  std::vector<std::shared_ptr<Action>> _awh;     // action warehouse
  std::vector<std::shared_ptr<Output>> _owh;     // output warehouse
  std::vector<std::shared_ptr<UserObject>> _uos; // user object warehouse

  std::shared_ptr<CommandLine> _command_line;
  std::shared_ptr<Parser> _parser;
  std::shared_ptr<System> _system;
  std::shared_ptr<Mesh> _mesh;
  std::shared_ptr<Executioner> _executioner;
};
